/*
 * Copyright (c) 2022 iSoftStone Information Technology (Group) Co.,Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.isoftstone.simplepiano.slice;

import com.isoftstone.simplepiano.AudioPlaybackCapabilityInterfaceProxy;

import com.isoftstone.simplepiano.ResourceTable;
import com.isoftstone.simplepiano.devices.SelectDeviceDialog;
import com.isoftstone.simplepiano.dialog.SelectRangeDialog;
import com.isoftstone.simplepiano.dialog.ShowExitDialog;
import com.isoftstone.simplepiano.utils.ConstantUtils;
import com.isoftstone.simplepiano.utils.WindowUtil;
import com.isoftstone.simplepiano.fraction.*;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.ability.IAbilityConnection;
import ohos.aafwk.ability.IAbilityContinuation;
import ohos.aafwk.ability.fraction.Fraction;
import ohos.aafwk.ability.fraction.FractionAbility;
import ohos.aafwk.ability.fraction.FractionManager;
import ohos.aafwk.ability.fraction.FractionScheduler;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.IntentParams;
import ohos.aafwk.content.Operation;
import ohos.agp.components.*;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.utils.Color;
import ohos.bundle.ElementName;
import ohos.distributedschedule.interwork.DeviceInfo;
import ohos.distributedschedule.interwork.DeviceManager;
import ohos.global.resource.Resource;
import ohos.multimodalinput.event.TouchEvent;
import ohos.rpc.IRemoteObject;
import ohos.rpc.RemoteException;

import java.util.*;

public class MainAbilitySlice extends AbilitySlice implements IAbilityContinuation {
    List<DeviceInfo> deviceInfoList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);
    private Button Transferred;
    private Text rangeDisplay;
    private boolean emptyDevice;

    private String data = null;

    //钢琴音频
    public static final int PLAY_AUDIO_MSG = 100;

    private static Button[] buttons;
    //选择结果
    private int selectRangeResult = -1;
    private int selectRegionValue = 1;
    private int selectGroupValue = 1;
    //屏幕宽度
    private int windowWidth;
    //当前fraction
    private BaseFraction mCurrentFraction;
    private BaseFraction oneFraction;
    private BaseFraction twoFraction;
    private BaseFraction threeFraction;
    private BaseFraction fourFraction;
    private BaseFraction fiveFraction;
    private BaseFraction sixFraction;
    private BaseFraction sevenFraction;

    private boolean isTag = true;

    //音频接口代理
    AudioPlaybackCapabilityInterfaceProxy PlayerAudioInterfaceProxy = null;
    //能力连接
    private final IAbilityConnection AudioAbilityConnection = new IAbilityConnection() {
        @Override
        public void onAbilityConnectDone(ElementName elementName, IRemoteObject iRemoteObject, int i) {
            PlayerAudioInterfaceProxy = new AudioPlaybackCapabilityInterfaceProxy(iRemoteObject);
        }

        @Override
        public void onAbilityDisconnectDone(ElementName elementName, int i) {
            PlayerAudioInterfaceProxy = null;
        }
    };

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        //获取屏幕宽度
        windowWidth = WindowUtil.getWindowWidth(getContext());
        initView();
        startLocalAudioPlay();
        initFraction();
    }

    private void initFraction() {
        oneFraction = new RangeOneFraction(this);
        twoFraction = new RangeTwoFraction(this);
        threeFraction = new RangeThreeFraction(this);
        fourFraction = new RangeFourFraction(this);
        fiveFraction = new RangeFiveFraction(this);
        sixFraction = new RangeSixFraction(this);
        sevenFraction = new RangeSevenFraction(this);
    }

    private void initView() {
        emptyDevice = this.deviceInfoList.isEmpty();
        Transferred = (Button) findComponentById(ResourceTable.Id_the_circulation);
        Transferred.setClickedListener(clickedListener);
        rangeDisplay = (Text) findComponentById(ResourceTable.Id_range_display);
        Button rangeSwitching = (Button) findComponentById(ResourceTable.Id_range_switching);
        rangeSwitching.setClickedListener(clickedListener);
        /*--------------------白键---------------------*/
        //大字二,一组白按键
        DirectionalLayout oneWhiteLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_one_whiteKeys);
        oneWhiteLayout.setTouchEventListener(touchEventListener);
        //大字组白按键
        DirectionalLayout twoWhiteLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_two_whiteKeys);
        twoWhiteLayout.setTouchEventListener(touchEventListener);
        //小字组白按键
        DirectionalLayout threeWhiteLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_three_whiteKeys);
        threeWhiteLayout.setTouchEventListener(touchEventListener);
        //小字一组白按键
        DirectionalLayout fourWhiteLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_four_whiteKeys);
        fourWhiteLayout.setTouchEventListener(touchEventListener);
        //小字二组白按键
        DirectionalLayout fiveWhiteLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_five_whiteKeys);
        fiveWhiteLayout.setTouchEventListener(touchEventListener);
        //小字三组白按键
        DirectionalLayout sixWhiteLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_six_whiteKeys);
        sixWhiteLayout.setTouchEventListener(touchEventListener);
        //小字四,五组白按键
        DirectionalLayout sevenWhiteLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_seven_whiteKeys);
        sevenWhiteLayout.setTouchEventListener(touchEventListener);

        /*--------------------黑键---------------------*/
        //大字二,一组黑按键
        DirectionalLayout oneBlackLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_one_backKeys);
        //大字组黑按键
        DirectionalLayout twoBlackLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_two_backKeys);
        //小字组黑按键
        DirectionalLayout threeBlackLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_three_backKeys);
        //小字一组黑按键
        DirectionalLayout fourBlackLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_four_backKeys);
        //小字二组黑按键
        DirectionalLayout fiveBlackLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_five_backKeys);
        //小字三组黑按键
        DirectionalLayout sixBlackLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_six_backKeys);
        //小字四,五组黑按键
        DirectionalLayout sevenBlackLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_seven_backKeys);

        if (data == null) {
            correspondingLayout(oneWhiteLayout, twoWhiteLayout, threeWhiteLayout, fiveWhiteLayout, sixWhiteLayout, sevenWhiteLayout, oneBlackLayout, twoBlackLayout, threeBlackLayout, fiveBlackLayout, sixBlackLayout, sevenBlackLayout);
        } else {
            switch (selectRangeResult) {
                case ConstantUtils.RANGE_ONE:
                    correspondingLayout(twoWhiteLayout, threeWhiteLayout, fourWhiteLayout, fiveWhiteLayout, sixWhiteLayout, sevenWhiteLayout, twoBlackLayout, threeBlackLayout, fourBlackLayout, fiveBlackLayout, sixBlackLayout, sevenBlackLayout);
                    rangeDisplay.setText("大字二、一组");
                    buttonStatusChange();
                    break;
                case ConstantUtils.RANGE_TWO:
                    correspondingLayout(oneWhiteLayout, threeWhiteLayout, fourWhiteLayout, fiveWhiteLayout, sixWhiteLayout, sevenWhiteLayout, oneBlackLayout, threeBlackLayout, fourBlackLayout, fiveBlackLayout, sixBlackLayout, sevenBlackLayout);
                    rangeDisplay.setText("大字组");
                    buttonStatusChange();
                    break;
                case ConstantUtils.RANGE_THREE:
                    correspondingLayout(oneWhiteLayout, twoWhiteLayout, fourWhiteLayout, fiveWhiteLayout, sixWhiteLayout, sevenWhiteLayout, oneBlackLayout, twoBlackLayout, fourBlackLayout, fiveBlackLayout, sixBlackLayout, sevenBlackLayout);
                    rangeDisplay.setText("小字组");
                    buttonStatusChange();
                    break;
                case ConstantUtils.RANGE_FOUR:
                    correspondingLayout(oneWhiteLayout, twoWhiteLayout, threeWhiteLayout, fiveWhiteLayout, sixWhiteLayout, sevenWhiteLayout, oneBlackLayout, twoBlackLayout, threeBlackLayout, fiveBlackLayout, sixBlackLayout, sevenBlackLayout);
                    rangeDisplay.setText("小字一组");
                    buttonStatusChange();
                    break;
                case ConstantUtils.RANGE_FIVE:
                    correspondingLayout(oneWhiteLayout, twoWhiteLayout, threeWhiteLayout, fourWhiteLayout, sixWhiteLayout, sevenWhiteLayout, oneBlackLayout, twoBlackLayout, threeBlackLayout, fourBlackLayout, sixBlackLayout, sevenBlackLayout);
                    rangeDisplay.setText("小字二组");
                    buttonStatusChange();
                    break;
                case ConstantUtils.RANGE_SIX:
                    correspondingLayout(oneWhiteLayout, twoWhiteLayout, threeWhiteLayout, fourWhiteLayout, fiveWhiteLayout, sevenWhiteLayout, oneBlackLayout, twoBlackLayout, threeBlackLayout, fourBlackLayout, fiveBlackLayout, sevenBlackLayout);
                    rangeDisplay.setText("小字三组");
                    buttonStatusChange();
                    break;
                case ConstantUtils.RANGE_SEVEN:
                    correspondingLayout(oneWhiteLayout, twoWhiteLayout, threeWhiteLayout, fourWhiteLayout, fiveWhiteLayout, sixWhiteLayout, oneBlackLayout, twoBlackLayout, threeBlackLayout, fourBlackLayout, fiveBlackLayout, sixBlackLayout);
                    rangeDisplay.setText("小字四、五组");
                    buttonStatusChange();
                    break;
            }
        }
        int[] buttonId = new int[88];
        buttonId[0] = ResourceTable.Id_PianoA2;
        buttonId[1] = ResourceTable.Id_PianoB2;

        buttonId[2] = ResourceTable.Id_PianoC1;
        buttonId[3] = ResourceTable.Id_PianoD1;
        buttonId[4] = ResourceTable.Id_PianoE1;
        buttonId[5] = ResourceTable.Id_PianoF1;
        buttonId[6] = ResourceTable.Id_PianoG1;
        buttonId[7] = ResourceTable.Id_PianoA1;
        buttonId[8] = ResourceTable.Id_PianoB1;

        buttonId[9] = ResourceTable.Id_PianoC;
        buttonId[10] = ResourceTable.Id_PianoD;
        buttonId[11] = ResourceTable.Id_PianoE;
        buttonId[12] = ResourceTable.Id_PianoF;
        buttonId[13] = ResourceTable.Id_PianoG;
        buttonId[14] = ResourceTable.Id_PianoA;
        buttonId[15] = ResourceTable.Id_PianoB;

        buttonId[16] = ResourceTable.Id_Pianoc;
        buttonId[17] = ResourceTable.Id_Pianod;
        buttonId[18] = ResourceTable.Id_Pianoe;
        buttonId[19] = ResourceTable.Id_Pianof;
        buttonId[20] = ResourceTable.Id_Pianog;
        buttonId[21] = ResourceTable.Id_Pianoa;
        buttonId[22] = ResourceTable.Id_Pianob;

        buttonId[23] = ResourceTable.Id_Pianoc1;
        buttonId[24] = ResourceTable.Id_Pianod1;
        buttonId[25] = ResourceTable.Id_Pianoe1;
        buttonId[26] = ResourceTable.Id_Pianof1;
        buttonId[27] = ResourceTable.Id_Pianog1;
        buttonId[28] = ResourceTable.Id_Pianoa1;
        buttonId[29] = ResourceTable.Id_Pianob1;

        buttonId[30] = ResourceTable.Id_Pianoc2;
        buttonId[31] = ResourceTable.Id_Pianod2;
        buttonId[32] = ResourceTable.Id_Pianoe2;
        buttonId[33] = ResourceTable.Id_Pianof2;
        buttonId[34] = ResourceTable.Id_Pianog2;
        buttonId[35] = ResourceTable.Id_Pianoa2;
        buttonId[36] = ResourceTable.Id_Pianob2;

        buttonId[37] = ResourceTable.Id_Pianoc3;
        buttonId[38] = ResourceTable.Id_Pianod3;
        buttonId[39] = ResourceTable.Id_Pianoe3;
        buttonId[40] = ResourceTable.Id_Pianof3;
        buttonId[41] = ResourceTable.Id_Pianog3;
        buttonId[42] = ResourceTable.Id_Pianoa3;
        buttonId[43] = ResourceTable.Id_Pianob3;

        buttonId[44] = ResourceTable.Id_Pianoc4;
        buttonId[45] = ResourceTable.Id_Pianod4;
        buttonId[46] = ResourceTable.Id_Pianoe4;
        buttonId[47] = ResourceTable.Id_Pianof4;
        buttonId[48] = ResourceTable.Id_Pianog4;
        buttonId[49] = ResourceTable.Id_Pianoa4;
        buttonId[50] = ResourceTable.Id_Pianob4;

        buttonId[51] = ResourceTable.Id_Pianoc5;

        buttonId[52] = ResourceTable.Id_PianoA2m;

        buttonId[53] = ResourceTable.Id_PianoC1m;
        buttonId[54] = ResourceTable.Id_PianoD1m;
        buttonId[55] = ResourceTable.Id_PianoF1m;
        buttonId[56] = ResourceTable.Id_PianoG1m;
        buttonId[57] = ResourceTable.Id_PianoA1m;

        buttonId[58] = ResourceTable.Id_PianoCm;
        buttonId[59] = ResourceTable.Id_PianoDm;
        buttonId[60] = ResourceTable.Id_PianoFm;
        buttonId[61] = ResourceTable.Id_PianoGm;
        buttonId[62] = ResourceTable.Id_PianoAm;

        buttonId[63] = ResourceTable.Id_Pianocm;
        buttonId[64] = ResourceTable.Id_Pianodm;
        buttonId[65] = ResourceTable.Id_Pianofm;
        buttonId[66] = ResourceTable.Id_Pianogm;
        buttonId[67] = ResourceTable.Id_Pianoam;

        buttonId[68] = ResourceTable.Id_Pianoc1m;
        buttonId[69] = ResourceTable.Id_Pianod1m;
        buttonId[70] = ResourceTable.Id_Pianof1m;
        buttonId[71] = ResourceTable.Id_Pianog1m;
        buttonId[72] = ResourceTable.Id_Pianoa1m;

        buttonId[73] = ResourceTable.Id_Pianoc2m;
        buttonId[74] = ResourceTable.Id_Pianod2m;
        buttonId[75] = ResourceTable.Id_Pianof2m;
        buttonId[76] = ResourceTable.Id_Pianog2m;
        buttonId[77] = ResourceTable.Id_Pianoa2m;

        buttonId[78] = ResourceTable.Id_Pianoc3m;
        buttonId[79] = ResourceTable.Id_Pianod3m;
        buttonId[80] = ResourceTable.Id_Pianof3m;
        buttonId[81] = ResourceTable.Id_Pianog3m;
        buttonId[82] = ResourceTable.Id_Pianoa3m;

        buttonId[83] = ResourceTable.Id_Pianoc4m;
        buttonId[84] = ResourceTable.Id_Pianod4m;
        buttonId[85] = ResourceTable.Id_Pianof4m;
        buttonId[86] = ResourceTable.Id_Pianog4m;
        buttonId[87] = ResourceTable.Id_Pianoa4m;

        buttons = new Button[88];
        for (int i = 0; i < buttons.length; i++) {
            buttons[i] = (Button) findComponentById(buttonId[i]);
        }
    }

    private void correspondingLayout(DirectionalLayout oneWhiteLayout, DirectionalLayout twoWhiteLayout, DirectionalLayout threeWhiteLayout, DirectionalLayout fiveWhiteLayout, DirectionalLayout sixWhiteLayout, DirectionalLayout sevenWhiteLayout, DirectionalLayout oneBlackLayout, DirectionalLayout twoBlackLayout, DirectionalLayout threeBlackLayout, DirectionalLayout fiveBlackLayout, DirectionalLayout sixBlackLayout, DirectionalLayout sevenBlackLayout) {
        oneWhiteLayout.setLayoutConfig(new DirectionalLayout.LayoutConfig(0, 0));
        oneBlackLayout.setLayoutConfig(new DirectionalLayout.LayoutConfig(0, 0));

        twoWhiteLayout.setLayoutConfig(new DirectionalLayout.LayoutConfig(0, 0));
        twoBlackLayout.setLayoutConfig(new DirectionalLayout.LayoutConfig(0, 0));

        threeWhiteLayout.setLayoutConfig(new DirectionalLayout.LayoutConfig(0, 0));
        threeBlackLayout.setLayoutConfig(new DirectionalLayout.LayoutConfig(0, 0));

        fiveWhiteLayout.setLayoutConfig(new DirectionalLayout.LayoutConfig(0, 0));
        fiveBlackLayout.setLayoutConfig(new DirectionalLayout.LayoutConfig(0, 0));

        sixWhiteLayout.setLayoutConfig(new DirectionalLayout.LayoutConfig(0, 0));
        sixBlackLayout.setLayoutConfig(new DirectionalLayout.LayoutConfig(0, 0));

        sevenWhiteLayout.setLayoutConfig(new DirectionalLayout.LayoutConfig(0, 0));
        sevenBlackLayout.setLayoutConfig(new DirectionalLayout.LayoutConfig(0, 0));
    }

    //设置触摸事件监听器
    private final Component.TouchEventListener touchEventListener = (component, touchEvent) -> {
        int pointerIndex = touchEvent.getIndex();
        int pointerId = touchEvent.getPointerId(pointerIndex);
        float x = touchEvent.getPointerPosition(pointerIndex).getX();
        float y = touchEvent.getPointerPosition(pointerIndex).getY();
        switch (touchEvent.getAction()) {
            case TouchEvent.PRIMARY_POINT_DOWN:
            case TouchEvent.OTHER_POINT_DOWN:
                onFingerPress(pointerId, x, y);
                break;
            case TouchEvent.OTHER_POINT_UP:
            case TouchEvent.PRIMARY_POINT_UP:
                onFingerLift(pointerId, x, y);
                break;
            case TouchEvent.POINT_MOVE:
                //获取一次事件中触控或轨迹追踪的指针数量
                int pointCount = touchEvent.getPointerCount();
                for (int i = 0; i < pointCount; i++) {
                    //getPointerPosition(i)获取一次事件中触控或轨迹追踪的某个指针相对于偏移位置的坐标
                    onFingerSlide(touchEvent.getPointerId(i), touchEvent.getPointerPosition(i).getX(), touchEvent.getPointerPosition(i).getY());
                }
                break;
            case TouchEvent.CANCEL:
                onAllFingersLift();
                break;
        }
        return true;
    };

    private final Component.ClickedListener clickedListener = new Component.ClickedListener() {
        @Override
        public void onClick(Component component) {
            switch (component.getId()) {
                case ResourceTable.Id_the_circulation:
                    if (!emptyDevice) {
                        if (Objects.equals(Transferred.getText(), ConstantUtils.TRANSFERRED)) {
                            showConnectionDialog();
                        } else if (Objects.equals(Transferred.getText(), ConstantUtils.IS_TRANSFERRED)) {
                            showExitCirculationDialog();
                        }
                    } else {
                        Transferred.setText("无可流转设备");
                    }
                    break;
                case ResourceTable.Id_range_switching:
                    showRangeDialog();
                    break;
            }
        }
    };

    private void showExitCirculationDialog() {
        ShowExitDialog showExitDialog = new ShowExitDialog(this);
        showExitDialog.show();
        //退出跨端迁移
        showExitDialog.setConfirmResultListener(this::reverseContinueAbility);
    }

    private void buttonStatusChange() {
        Transferred.setText("已流转");
        Transferred.setTextColor(new Color(Color.rgb(169, 169, 169)));
    }

    /*------------------------------触摸相关处理-------------------------------*/
    private final HashMap<Integer, Integer> keyMap = new HashMap<>();

    //手指按下
    private void onFingerPress(int index, float x, float y) {
        int key = isInScale(x, y);
        if (key != -1) {
            fireKeyPress(key);
            this.keyMap.put(index, key);
        }
    }

    private void onFingerLift(int index, float x, float y) {
        if (this.keyMap.get(index) != null) {
            int key = this.keyMap.get(index);
            fireKeyLift(key);
            this.keyMap.remove(index);
        } else {
            int newKey = isInScale(x, y);
            if (newKey != -1) {
                fireKeyLift(newKey);
            }
        }
    }


    private void onFingerSlide(int index, float x, float y) {
        //当前按键key
        int currentKey = isInScale(x, y);
        if (currentKey != -1) {
            if (this.keyMap.get(index) != null) {
                int newKey = this.keyMap.get(index);
                if ((currentKey >= 0) && (currentKey != newKey)) {
                    fireKeyPress(currentKey);
                    fireKeyLift(newKey);
                    this.keyMap.put(index, currentKey);
                }
            }
        }
    }

    //所有手指
    private void onAllFingersLift() {
        for (Integer integer : this.keyMap.values()) {
            fireKeyLift(integer);
        }
        this.keyMap.clear();
    }

    private void fireKeyLift(int key) {
        switch (selectRangeResult) {
            case ConstantUtils.RANGE_ONE:
                keyEffect(key, 9, ResourceTable.Media_black_key, ResourceTable.Media_white_key);
                break;
            case ConstantUtils.RANGE_SEVEN:
                keyEffect(key, 8, ResourceTable.Media_black_key, ResourceTable.Media_white_key);
                break;
            default:
                keyEffect(key, 7, ResourceTable.Media_black_key, ResourceTable.Media_white_key);
        }
    }

    private void keyEffect(int key, int i, int effect1, int effect2) {
        if (key >= i) {
            PixelMapElement blackElement = getElement(effect1);
            //黑色按钮效果
            switch (selectRangeResult) {
                case ConstantUtils.RANGE_ONE:
                    buttons[key + 43].setBackground(blackElement);
                    break;
                case ConstantUtils.RANGE_TWO:
                    buttons[key + 51].setBackground(blackElement);
                    break;
                case ConstantUtils.RANGE_THREE:
                    buttons[key + 56].setBackground(blackElement);
                    break;
                case ConstantUtils.RANGE_FIVE:
                    buttons[key + 66].setBackground(blackElement);
                    break;
                case ConstantUtils.RANGE_SIX:
                    buttons[key + 71].setBackground(blackElement);
                    break;
                case ConstantUtils.RANGE_SEVEN:
                    buttons[key + 75].setBackground(blackElement);
                    break;
                default:
                    buttons[key + 61].setBackground(blackElement);
            }
        } else {
            PixelMapElement whiteElement = getElement(effect2);
            //白色色按钮效果
            switch (selectRangeResult) {
                case ConstantUtils.RANGE_ONE:
                    buttons[key].setBackground(whiteElement);
                    break;
                case ConstantUtils.RANGE_TWO:
                    buttons[key + 9].setBackground(whiteElement);
                    break;
                case ConstantUtils.RANGE_THREE:
                    buttons[key + 16].setBackground(whiteElement);
                    break;
                case ConstantUtils.RANGE_FIVE:
                    buttons[key + 30].setBackground(whiteElement);
                    break;
                case ConstantUtils.RANGE_SIX:
                    buttons[key + 37].setBackground(whiteElement);
                    break;
                case ConstantUtils.RANGE_SEVEN:
                    buttons[key + 44].setBackground(whiteElement);
                    break;
                default:
                    buttons[key + 23].setBackground(whiteElement);
            }
        }
    }

    private void fireKeyPress(int key) {
        //播放音乐
        PlayAudio(key);
        switch (selectRangeResult) {
            case ConstantUtils.RANGE_ONE:
                keyEffect(key, 9, ResourceTable.Media_black_key_press, ResourceTable.Media_white_key_press);
                break;
            case ConstantUtils.RANGE_SEVEN:
                keyEffect(key, 8, ResourceTable.Media_black_key_press, ResourceTable.Media_white_key_press);
                break;
            default:
                keyEffect(key, 7, ResourceTable.Media_black_key_press, ResourceTable.Media_white_key_press);
                break;
        }
    }

    private PixelMapElement getElement(int p) {
        Resource whiteResource = null;
        try {
            whiteResource = getResourceManager().getResource(p);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new PixelMapElement(whiteResource);
    }

    private void PlayAudio(int indexPressedKey) {
        try {
            PlayerAudioInterfaceProxy.sendCommand(PLAY_AUDIO_MSG, indexPressedKey, selectRangeResult);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    //判断某个点是否在某个按钮的范围内
    private int isInScale(float x, float y) {
        int i = -1;
        int width = windowWidth / 7;
        if (data == null) {
            i = getKey(x, y, i, width, 0.5, 1.2, 7, 1.8, 2.55, 8, 3.5, 4.2, 9, 4.65, 5.35, 10, 5.8, 6.55, 11);
        } else {
            switch (selectRangeResult) {
                case ConstantUtils.RANGE_ONE:
                    width = windowWidth / 9;
                    i = getOtherKey(x, y, i, width);
                    break;
                case ConstantUtils.RANGE_TWO:
                case ConstantUtils.RANGE_THREE:
                case ConstantUtils.RANGE_FOUR:
                case ConstantUtils.RANGE_FIVE:
                case ConstantUtils.RANGE_SIX:
                    i = getKey(x, y, i, width, 0.5, 1.2, 7, 1.8, 2.55, 8, 3.5, 4.2, 9, 4.65, 5.35, 10, 5.8, 6.55, 11);
                    break;
                case ConstantUtils.RANGE_SEVEN:
                    width = windowWidth / 8;
                    i = getKey(x, y, i, width, 0.55, 1.3, 8, 1.65, 2.4, 9, 3.4, 4.15, 10, 4.5, 5.25, 11, 5.6, 6.35, 12);
                    break;
            }
        }
        return i;
    }

    //大字二,一组
    private int getOtherKey(float x, float y, int i, int width) {
        if (y > 500) {
            i = (int) (x / width);
        } else {
            if (x > width * 0.8 && x < width * 1.5) {
                i = 9;
            } else if (x > width * 2.55 && x < width * 3.3) {
                i = 10;
            } else if (x > width * 3.7 && x < width * 4.4) {
                i = 11;
            } else if (x > width * 5.5 && x < width * 6.2) {
                i = 12;
            } else if (x > width * 6.6 && x < width * 7.35) {
                i = 13;
            } else if (x > width * 7.75 && x < width * 8.5) {
                i = 14;
            }
        }
        return i;
    }

    //大字组,小字组,小字一,二,三,四组
    private int getKey(float x, float y, int i, int width, double v, double v2, int i2, double v3, double v4, int i3, double v5, double v6, int i4, double v7, double v8, int i5, double v9, double v10, int i6) {
        if (y > 500) {
            i = (int) (x / width);
        } else {
            if (x > width * v && x < width * v2) {
                i = i2;
            } else if (x > width * v3 && x < width * v4) {
                i = i3;
            } else if (x > width * v5 && x < width * v6) {
                i = i4;
            } else if (x > width * v7 && x < width * v8) {
                i = i5;
            } else if (x > width * v9 && x < width * v10) {
                i = i6;
            }
        }
        return i;
    }


    /*--------------------------------音域选择----------------------------------*/
    private void showRangeDialog() {
        SelectRangeDialog selectRangeDialog = new SelectRangeDialog(this);
        selectRangeDialog.show();
        selectRangeDialog.setResultListener((regionValue, groupValue) -> {
            selectRegionValue = regionValue;
            selectGroupValue = groupValue;
            switch (selectRegionValue) {
                case ConstantUtils.BASS_AREA:
                    setSelectResult(0, ConstantUtils.RANGE_ONE, 1, ConstantUtils.RANGE_TWO);
                    break;
                case ConstantUtils.ALTO_SECTION:
                    if (selectGroupValue == 0) {
                        selectRangeResult = ConstantUtils.RANGE_THREE;
                    } else setSelectResult(1, ConstantUtils.RANGE_FOUR, 2, ConstantUtils.RANGE_FIVE);
                    break;
                case ConstantUtils.TREBLE:
                    setSelectResult(0, ConstantUtils.RANGE_SIX, 1, ConstantUtils.RANGE_SEVEN);
                    break;
            }
            setRangeLayout(selectRangeResult);
        });
        if (selectRangeResult != -1) {
            selectRangeDialog.seTValue(selectRegionValue, selectGroupValue);
        }
    }

    private void setSelectResult(int i, int rangeOne, int i2, int rangeTwo) {
        if (selectGroupValue == i) {
            selectRangeResult = rangeOne;
        } else if (selectGroupValue == i2) {
            selectRangeResult = rangeTwo;
        }
    }

    private BaseFraction showFraction;

    private void setRangeLayout(int selectRangeResult) {
        switch (selectRangeResult) {
            case ConstantUtils.RANGE_ONE:
                showFraction = oneFraction;
                rangeSelection();
                rangeDisplay.setText("大字二、一组");
                break;
            case ConstantUtils.RANGE_TWO:
                showFraction = twoFraction;
                rangeSelection();
                rangeDisplay.setText("大字组");
                break;
            case ConstantUtils.RANGE_THREE:
                showFraction = threeFraction;
                rangeSelection();
                rangeDisplay.setText("小字组");
                break;
            case ConstantUtils.RANGE_FOUR:
                showFraction = fourFraction;
                rangeSelection();
                rangeDisplay.setText("小字一组");
                break;
            case ConstantUtils.RANGE_FIVE:
                showFraction = fiveFraction;
                rangeSelection();
                rangeDisplay.setText("小字二组");
                break;
            case ConstantUtils.RANGE_SIX:
                showFraction = sixFraction;
                rangeSelection();
                rangeDisplay.setText("小字三组");
                break;
            case ConstantUtils.RANGE_SEVEN:
                showFraction = sevenFraction;
                rangeSelection();
                rangeDisplay.setText("小字四、五组");
                break;
            default:
                break;
        }
    }

    private void rangeSelection() {
        FractionManager fractionManager = ((FractionAbility) getAbility()).getFractionManager();
        FractionScheduler fractionScheduler = fractionManager.startFractionScheduler();
        Optional<Fraction> fractionByTag = fractionManager.getFractionByTag(showFraction.fractionName());

        if (mCurrentFraction != null) {
            fractionScheduler.hide(mCurrentFraction);
        }
        if (fractionByTag != null && fractionByTag.isPresent()) {
            fractionScheduler.show(fractionByTag.get());
        } else {
            fractionScheduler.add(ResourceTable.Id_range_key, showFraction, showFraction.fractionName());
            fractionScheduler.show(showFraction);
        }

        fractionScheduler.submit();
        mCurrentFraction = showFraction;
        //fractionScheduler.replace(ResourceTable.Id_range_key,showFraction);
        //fractionScheduler.submit();
    }


    /*---------------------------------跨端迁移-----------------------------------*/
    private final List<DeviceInfo> devices = new ArrayList<>();
    private final List<String> saveDevices = new ArrayList<>();

    private void showConnectionDialog() {
        SelectRangeDialog selectRangeDialog = new SelectRangeDialog(this);
        selectRangeDialog.show();
        selectRangeDialog.setResultListener((regionValue, groupValue) -> {
            selectRegionValue = regionValue;
            selectGroupValue = groupValue;
            switch (selectRegionValue) {
                case ConstantUtils.BASS_AREA:
                    setSelectResult(0, ConstantUtils.RANGE_ONE, 1, ConstantUtils.RANGE_TWO);
                    break;
                case ConstantUtils.ALTO_SECTION:
                    if (selectGroupValue == 0) {
                        selectRangeResult = ConstantUtils.RANGE_THREE;
                    } else setSelectResult(1, ConstantUtils.RANGE_FOUR, 2, ConstantUtils.RANGE_FIVE);
                    break;
                case ConstantUtils.TREBLE:
                    setSelectResult(0, ConstantUtils.RANGE_SIX, 1, ConstantUtils.RANGE_SEVEN);
                    break;
            }
            getDevices();
        });
    }

    private void getDevices() {
        if (devices.size() > 0) {
            devices.clear();
        }
        devices.addAll(deviceInfoList);
        showDevicesDialog();
    }

    private void showDevicesDialog() {
        new SelectDeviceDialog(this, devices, deviceInfo -> {
            saveDevices.add(deviceInfo.getDeviceId());
            //跨端迁移
            continueAbility(deviceInfo.getDeviceId());
        }).deviceShow();
        if (isTag) {
            //替换当前布局
            try {
                ReplaceCurrentLayout();
            } catch (Exception e) {
                e.printStackTrace();
            }
            isTag = false;
        }

    }

    private void ReplaceCurrentLayout() {
        showFraction = fourFraction;
        rangeSelection();
        rangeDisplay.setText("小字一组");
    }

    private void startLocalAudioPlay() {
        Intent localIntent = new Intent();
        Operation localOperation = new Intent.OperationBuilder()
                .withBundleName(getBundleName())
                .withAbilityName(ConstantUtils.AUDIO_ABILITY_MAIN)
                .withFlags(Intent.FLAG_START_FOREGROUND_ABILITY)
                .build();
        localIntent.setOperation(localOperation);
        startAbility(localIntent);
        //本地音频播放能力连接
        connectAbility(localIntent, AudioAbilityConnection);
    }

    //开始迁移 AbilitySlice可以不实现默认返回true
    @Override
    public boolean onStartContinuation() {
        return true;
    }

    @Override
    public boolean onSaveData(IntentParams intentParams) {
        intentParams.setParam("data", "remote");
        intentParams.setParam(ConstantUtils.RANGE_RESULT, selectRangeResult);
        return true;
    }

    @Override
    public boolean onRestoreData(IntentParams intentParams) {
        data = intentParams.getParam("data").toString();
        selectRangeResult = Integer.parseInt(intentParams.getParam(ConstantUtils.RANGE_RESULT).toString());
        return true;
    }

    @Override
    public void onCompleteContinuation(int i) {
    }

    //远程终止
    @Override
    public void onRemoteTerminated() {
        IAbilityContinuation.super.onRemoteTerminated();
    }

    @Override
    protected void onActive() {
        super.onActive();
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

}
